-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-74025] Extract inline JavaScript from checkboxContent.jelly
#374
Conversation
|
||
height = Math.floor(height); | ||
document.getElementById(`ecp_${randomName}`).style.height = height + "px"; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PRs to update this code pattern on this repo, @yaroslavafenkin !
I was looking at the changes on these PRs, and it occurred to me that if we moved the inline functions to this file as a function, then we could call that in these forEach
loop, while also being able to write tests to verify those functions. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I could look into that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to figure out to approach this.
If I just extract the function like this:
Index: src/main/resources/org/biouno/unochoice/common/checkbox-content.js
<+>UTF-8
===================================================================
diff --git a/src/main/resources/org/biouno/unochoice/common/checkbox-content.js b/src/main/resources/org/biouno/unochoice/common/checkbox-content.js
--- a/src/main/resources/org/biouno/unochoice/common/checkbox-content.js (revision 91aee0743ce607987513b2823e23dfdbc6da2135)
+++ b/src/main/resources/org/biouno/unochoice/common/checkbox-content.js (date 1731325784805)
@@ -2,18 +2,22 @@
document.querySelectorAll(".checkbox-content-data-holder").forEach((dataHolder) => {
const { maxCount, randomName } = dataHolder.dataset;
- var height = 0;
- var refElement = document.getElementById(`ecp_${randomName}_0`);
- if (maxCount > 0 && refElement && refElement.offsetHeight != 0) {
- for (var i = 0; i < maxCount; i++) {
- height += refElement.offsetHeight + 3;
- }
- }
- else {
- height = maxCount * 25.5;
- }
+ setHeight(maxCount, randomName);
+ });
+});
+
+function setHeight(maxCount, randomName) {
+ var height = 0;
+ var refElement = document.getElementById(`ecp_${randomName}_0`);
+ if (maxCount > 0 && refElement && refElement.offsetHeight != 0) {
+ for (var i = 0; i < maxCount; i++) {
+ height += refElement.offsetHeight + 3;
+ }
+ }
+ else {
+ height = maxCount * 25.5;
+ }
- height = Math.floor(height);
- document.getElementById(`ecp_${randomName}`).style.height = height + "px";
- });
-});
+ height = Math.floor(height);
+ document.getElementById(`ecp_${randomName}`).style.height = height + "px";
+}
I won't have access to the setHeight
function in *.test.js
. I tried to mark it as exported so that I can access it in a unit test, but that makes Java tests fail with
org.htmlunit.corejs.javascript.EvaluatorException: identifier is a reserved word: export (http://localhost:54289/jenkins/adjuncts/a326e762/org/biouno/unochoice/common/checkbox-content.js#9)
and with a lot of entries in the stack trace containing htmlunit
.
Another option I thought of is moving the setHeight
function to Util.ts
. But it's a little different that other functions there. It doesn't return anything, but just modifies the state of a DOM element depending also on some data in another DOM element. Without any further refactoring and given its reliance on DOM can this even be tested?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be easier to use Jest with an update to its current config that only loads typescript files (or you can write it in TS if you prefer), e.g. after applying your diff (thanks for that!!!):
diff --git a/package.json b/package.json
index 4b962b2..b0f4f2c 100644
--- a/package.json
+++ b/package.json
@@ -67,7 +67,8 @@
"jest-junit"
],
"testMatch": [
- "<rootDir>/src/test/js/*.test.ts"
+ "<rootDir>/src/test/js/*.test.ts",
+ "<rootDir>/src/test/js/*.test.js"
]
}
}
diff --git a/src/main/resources/org/biouno/unochoice/common/checkbox-content.js b/src/main/resources/org/biouno/unochoice/common/checkbox-content.js
index 39d8add..21bb678 100644
--- a/src/main/resources/org/biouno/unochoice/common/checkbox-content.js
+++ b/src/main/resources/org/biouno/unochoice/common/checkbox-content.js
@@ -2,18 +2,22 @@ window.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".checkbox-content-data-holder").forEach((dataHolder) => {
const { maxCount, randomName } = dataHolder.dataset;
- var height = 0;
- var refElement = document.getElementById(`ecp_${randomName}_0`);
- if (maxCount > 0 && refElement && refElement.offsetHeight != 0) {
- for (var i = 0; i < maxCount; i++) {
- height += refElement.offsetHeight + 3;
- }
- }
- else {
- height = maxCount * 25.5;
- }
-
- height = Math.floor(height);
- document.getElementById(`ecp_${randomName}`).style.height = height + "px";
+ setHeight(maxCount, randomName);
});
});
+
+function setHeight(maxCount, randomName) {
+ var height = 0;
+ var refElement = document.getElementById(`ecp_${randomName}_0`);
+ if (maxCount > 0 && refElement && refElement.offsetHeight != 0) {
+ for (var i = 0; i < maxCount; i++) {
+ height += refElement.offsetHeight + 3;
+ }
+ }
+ else {
+ height = maxCount * 25.5;
+ }
+
+ height = Math.floor(height);
+ document.getElementById(`ecp_${randomName}`).style.height = height + "px";
+}
Then running yarn run test
finds the extra test, and it passes successfully (although the test is not doing anything useful right now). I think we will have to use jsdom do prepare the elements for setHeight
to be called, and then test a few scenarios 👍
Let me know if that helps.
Cheers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TS is fine for me to use.
I've created checkbox-content.test.ts
in src/test/js
. Here's its content (without imports, as those require tweaks depending on the approach taken):
describe('setHeight', () => {
test('Sets the correct height on the element', () => {
const randomName: string = "randomNameIndeed";
const maxCount: number = 13;
document.body.innerHTML = `<body><div id="ecp_${randomName}_0"></div><div id="ecp_${randomName}"></div></body>`;
const target = document.querySelector(`#ecp_${randomName}`);
expect(target.style.height).not.toBe("331px");
setHeight(maxCount, randomName);
expect(target.style.height).toBe("331px");
});
});
Now there are few paths when it comes to code arrangement:
- Leaving
setHeight
incheckbox-content.js
. To be able to call the function in a test I've tried adding theexport
keyword before thefunction
keyword incheckbox-content.js
. Runningnpm run test
results in log telling mesetHeight
is not defined. - I've tried to move the
setHeight
toUtil.ts
. With that I was able to write a test that passed just fine. I went to test whether everything still worked in the Jenkins UI, and it didn't.Util.js
isn't included into the page asUnoChoice.js
is. I could appendUtil.js
somewhere here, then it would work. Would pollute the page with unneeded object though. - I've tried to move the
setHeight
toUnoChoice.es6
as that one is exported and included into the page already. I cannot import thesetHeight
fromUnoChoice.es6
in a test though. First of all.es6
isn't a module extension recognized by jest. I was able to get past that by changing jest's config, but then I get the following error:
C:\projects\active-choices-plugin\src\main\resources\org\biouno\unochoice\stapler\unochoice\UnoChoice.es6:24
import Util from './Util.ts';
^^^^^^
SyntaxError: Cannot use import statement outside a module
1 | import {describe, test} from '@jest/globals';
> 2 | import UnoChoice from '../../main/resources/org/biouno/unochoice/stapler/unochoice/UnoChoice.es6';
| ^
3 | import expect from "expect";
4 |
5 | import jQuery from "jquery";
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @kinow, I wanted to let you know that this plugin is now in the top 3 of plugins with CSP violations and unreleased CSP fixes by popularity (along with Blue Ocean and Artifactory). Our contract with Alpha Omega lasts until the end of the year, so ideally we could get this plugin released with CSP fixes in the next few weeks while we still have staffing to work on it. While the risk of regression is low with CSP changes, releasing a few weeks before the end of the year would also give us time to address any regressions in the unlikely case that any are reported. Historically Jenkins activity slows down a lot in the month of December as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @basil, the CSP violations are fixed by these inline extraction pull requests? If so, I'd be happy to review & merge them without the extra work to refactor it and write the tests (as these would be tests for existing code, and not for new code). I'd just open a new issue to work on that later.
WDYT?
BTW, @basil, I saw some plugins are using GitHub issues... would you know if it'd be possible for a plugin with JIRA issues to migrate to GitHub issues, please?
Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Releasing the existing PRs and working on refactoring for test coverage in a separate issue sounds great to me. That would enable us to get some soak time for the production change while the project is still being funded.
I believe there was a thread on the developer mailing list about migrating to GitHub issues but I do not remember the current status. I believe that you can enable GitHub issues for this repository in the GitHub UI and set a flag in jenkins-infra/repository-permissions-updater
to show a link to GitHub issues on the plugin site. Not sure about migrating existing Jira issues to GitHub issues. (Indeed, a high-fidelity migration covering all existing use cases was my main concern the last time this topic was discussed.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Releasing the existing PRs and working on refactoring for test coverage in a separate issue sounds great to me. That would enable us to get some soak time for the production change while the project is still being funded.
Roger that, then I can try to release it by the end of this weekend, so that we have it ready for testing over next week (90% sure I can do that, but family/life/$work/etc comes first, as you know).
I believe there was a thread on the developer mailing list about migrating to GitHub issues but I do not remember the current status. I believe that you can enable GitHub issues for this repository in the GitHub UI and set a flag in jenkins-infra/repository-permissions-updater to show a link to GitHub issues on the plugin site.
Some time ago I found a similar thread, I think I know how to enable it on a project.
Not sure about migrating existing Jira issues to GitHub issues. (Indeed, a high-fidelity migration covering all existing use cases was my main concern the last time this topic was discussed.)
Yeah, that's what I couldn't find before. I think the... GitLab plugin was the first plugin I saw using GitHub issues. But that's lower priority than releasing it. I will review & merge it, open the new issue in JIRA, do some triaging on the issues to see if there's anything else simple that could be added, and then cut the release. While others test it, then, I will see if I can work on moving this and maybe tap-plugin both to GitHub issues.
Cheers
https://issues.jenkins.io/browse/JENKINS-74025
Testing done
Created a freestyle project with 2 Active Choices Parameters. Took sample Groovy scripts from the README. Choice type - Check Boxes.
Before the change
After the change
Submitter checklist